#pragma once

#include "DBManager/IRepository/Input/Property/IPCOMPGRepository.h"
#include "DBManager/Repository/HDF5/Base/MainlyRepositoryBase.h"
#include "highfive/H5File.hpp"
SG_DBMANAGER_HDF5_NAMESPACE_OPEN
namespace PCOMPG {
struct IDENTITY {
  SG::DataStructure::Common::Id PID = 0;       ///<
  SG::DataStructure::Common::I64 NPLIES = 0;   ///<
  SG::DataStructure::Common::Real Z0 = 0.0;    ///<
  SG::DataStructure::Common::Real NSM = 0.0;   ///<
  SG::DataStructure::Common::Real SB = 0.0;    ///<
  SG::DataStructure::Common::I64 FT = 0;       ///<
  SG::DataStructure::Common::Real TREF = 0.0;  ///<
  SG::DataStructure::Common::Real GE = 0.0;    ///<
  char MICRO[4] = {0};                         ///<
  SG::DataStructure::Common::I64 PLY_POS =
      0;  ///< Start position of PLY data in the PLY dataset
  SG::DataStructure::Common::I64 PLY_LEN =
      0;  ///< Length of PLY data in the PLY dataset
  SG::DataStructure::Common::Id DOMAIN_ID = 0;  ///<
};
};  // namespace PCOMPG
SG_DBMANAGER_HDF5_NAMESPACE_CLOSE
template <>
inline HighFive::DataType
HighFive::create_datatype<SG::DBManager::HDF5::PCOMPG::IDENTITY>() {
  HighFive::CompoundType compoundType = {
      {"PID", HighFive::create_datatype<SG::DataStructure::Common::Id>()},
      {"NPLIES", HighFive::create_datatype<SG::DataStructure::Common::I64>()},
      {"Z0", HighFive::create_datatype<SG::DataStructure::Common::Real>()},
      {"NSM", HighFive::create_datatype<SG::DataStructure::Common::Real>()},
      {"SB", HighFive::create_datatype<SG::DataStructure::Common::Real>()},
      {"FT", HighFive::create_datatype<SG::DataStructure::Common::I64>()},
      {"TREF", HighFive::create_datatype<SG::DataStructure::Common::Real>()},
      {"GE", HighFive::create_datatype<SG::DataStructure::Common::Real>()},
      {"MICRO", HighFive::create_datatype<char[4]>(), 1, true},
      {"PLY_POS", HighFive::create_datatype<SG::DataStructure::Common::I64>()},
      {"PLY_LEN", HighFive::create_datatype<SG::DataStructure::Common::I64>()},
      {"DOMAIN_ID",
       HighFive::create_datatype<SG::DataStructure::Common::Id>()}};
  return compoundType;
}

template <>
inline HighFive::DataType
HighFive::create_datatype<SG::DataStructure::FEM::PCOMPGData::PLYData>() {
  HighFive::CompoundType ct = {
      {"GPLYID", HighFive::create_datatype<SG::DataStructure::Common::Id>()},
      {"MID", HighFive::create_datatype<SG::DataStructure::Common::Id>()},
      {"THICK", HighFive::create_datatype<SG::DataStructure::Common::Real>()},
      {"THETA", HighFive::create_datatype<SG::DataStructure::Common::Real>()},
      {"SOUT", HighFive::create_datatype<SG::DataStructure::Common::I64>()},
      {"MIDMTX", HighFive::create_datatype<SG::DataStructure::Common::Id>()},
      {"VF", HighFive::create_datatype<SG::DataStructure::Common::Real>()},
      {"VV", HighFive::create_datatype<SG::DataStructure::Common::Real>()},
      {"CTEMP", HighFive::create_datatype<SG::DataStructure::Common::Real>()},
      {"MOIST", HighFive::create_datatype<SG::DataStructure::Common::Real>()},
      {"CRIT", HighFive::create_datatype<char[4]>(), 1, true},
      {"NFTI", HighFive::create_datatype<SG::DataStructure::Common::I64>()},
      {"FTI", HighFive::create_datatype<char[96]>(), 1, true},
      {"GEFLG", HighFive::create_datatype<SG::DataStructure::Common::I64>()}};
  return ct;
}
SG_DBMANAGER_HDF5_NAMESPACE_OPEN
class PCOMPGRepository : public IPCOMPGRepository,
                         public SG::DBManager::HDF5::MainlyRepositoryBase<
                             SG::DataStructure::FEM::PCOMPGData> {
  using MainStruct = SG::DataStructure::FEM::PCOMPGData;
  using SubStructPLY = SG::DataStructure::FEM::PCOMPGData::PLYData;

  using NasMainStruct = SG::DBManager::HDF5::PCOMPG::IDENTITY;

 public:
  explicit PCOMPGRepository(HDF5Database& database);

  enum DATASET : std::uint8_t { MainDataset, IndexDataset, SubDataset_PLY };

  /**
   * @brief   : 初始化表数据
   * @author  : wuxingchuang
   */
  void InitialDatasetInfo() override;

  /**
   * @brief   : 将缓存数据转储到文件内
   */
  void DumpWriteCahce() override;

  /**
   * @brief   : 加载文件数据至缓存
   * @param   : loadIndex
   */
  std::vector<DataType>* LoadReadCache(std::size_t loadIndex) override;

  /**
   * @brief   : 对数据进行排序
   */
  void SortData() override;

  /**
   * @brief   : 获取所有数据
   */
  std::vector<MainStruct> GetAllData() override;

  /**
   * @brief   : 将自己的数据转存为nastran的数据结构
   */
  void OwnToNastran(std::vector<MainStruct>& own,
                    std::vector<NasMainStruct>& _OUT IDENTITYData,
                    std::vector<SubStructPLY>& _OUT subDataPLY,

                    bool isSort = false);

  /**
   * @brief   : 将NASTRAN的数据转存为自己的数据结构
   * @param   : IDENTITYData
   * @param   : subData
   * @param   : own
   */
  void NastranToOwn(std::vector<NasMainStruct>& IDENTITYData,
                    std::vector<SubStructPLY>& subDataPLY,
                    std::vector<MainStruct>& _OUT own);
};
SG_DBMANAGER_HDF5_NAMESPACE_CLOSE
